import SwiftUI
//类似安卓的FlexboxLayout，弹性盒布局
struct FlexboxLayout: Layout {
    /// 子元素之间的水平间距
    var horizontalSpacing: CGFloat = 8
    /// 子元素之间的垂直间距
    var verticalSpacing: CGFloat = 8
    
    func sizeThatFits(
        proposal: ProposedViewSize,
        subviews: Subviews,
        cache: inout ()
    ) -> CGSize {
        let maxWidth = proposal.width ?? 0
        var currentRowWidth: CGFloat = 0
        var currentRowHeight: CGFloat = 0
        var totalHeight: CGFloat = 0
        
        for subview in subviews {
            let subviewSize = subview.sizeThatFits(proposal)
            let requiredWidth = currentRowWidth == 0
                ? subviewSize.width
                : currentRowWidth + horizontalSpacing + subviewSize.width
            
            if requiredWidth > maxWidth {
                totalHeight += currentRowHeight + verticalSpacing
                currentRowWidth = subviewSize.width
                currentRowHeight = subviewSize.height
            } else {
                currentRowWidth = requiredWidth
                currentRowHeight = max(currentRowHeight, subviewSize.height)
            }
        }
        
        totalHeight += currentRowHeight
        return CGSize(width: maxWidth, height: totalHeight)
    }
    
    func placeSubviews(
        in bounds: CGRect,
        proposal: ProposedViewSize,
        subviews: Subviews,
        cache: inout ()
    ) {
        let maxWidth = bounds.width
        var currentY = bounds.minY  // 当前行的基准Y坐标（行顶部）
        var currentRowSubviews: [(view: LayoutSubview, size: CGSize)] = []  // 当前行的子元素
        var currentRowTotalWidth: CGFloat = 0  // 当前行总宽度（含间距）
        var currentRowMaxHeight: CGFloat = 0   // 当前行最大高度（决定行高）
        
        for subview in subviews {
            let subviewSize = subview.sizeThatFits(proposal)
            let requiredWidth = currentRowSubviews.isEmpty
                ? subviewSize.width
                : currentRowTotalWidth + horizontalSpacing + subviewSize.width
            
            if requiredWidth > maxWidth {
                // 处理当前行（垂直居中放置）
                placeCurrentRow(
                    in: bounds,
                    baseY: currentY,  // 行顶部Y坐标
                    maxWidth: maxWidth,
                    subviews: currentRowSubviews,
                    totalWidth: currentRowTotalWidth,
                    maxHeight: currentRowMaxHeight
                )
                
                // 换行准备
                currentY += currentRowMaxHeight + verticalSpacing
                currentRowSubviews = [(subview, subviewSize)]
                currentRowTotalWidth = subviewSize.width
                currentRowMaxHeight = subviewSize.height
            } else {
                currentRowSubviews.append((subview, subviewSize))
                currentRowTotalWidth = requiredWidth
                currentRowMaxHeight = max(currentRowMaxHeight, subviewSize.height)
            }
        }
        
        // 处理最后一行
        if !currentRowSubviews.isEmpty {
            placeCurrentRow(
                in: bounds,
                baseY: currentY,
                maxWidth: maxWidth,
                subviews: currentRowSubviews,
                totalWidth: currentRowTotalWidth,
                maxHeight: currentRowMaxHeight
            )
        }
    }
    
    // 放置一行子元素（垂直居中核心逻辑）
    private func placeCurrentRow(
        in bounds: CGRect,
        baseY: CGFloat,  // 行的顶部Y坐标
        maxWidth: CGFloat,
        subviews: [(view: LayoutSubview, size: CGSize)],
        totalWidth: CGFloat,
        maxHeight: CGFloat  // 行的总高度（由最高元素决定）
    ) {
        var currentX = bounds.minX  // 水平起始位置（左对齐，如需水平居中可加偏移）
        
        for (subview, size) in subviews {
            // 垂直居中计算：子视图Y坐标 = 行顶部Y + (行高 - 子视图高度) / 2
            let subviewY = baseY + (maxHeight - size.height) / 2
            
            subview.place(
                at: CGPoint(x: currentX, y: subviewY),
                proposal: ProposedViewSize(size)
            )
            
            currentX += size.width + horizontalSpacing
        }
    }
}

// 使用示例（包含不同高度的子视图，方便测试垂直居中）
struct FlexboxLayoutDemo: View {
    let tags = [
        ("短文本", 12),
        ("中等长度文本", 16),
        ("很长很长的文本内容", 20),
        ("测试", 14),
        ("垂直居中效果", 18),
        ("Layout", 15),
        ("SwiftUI", 22),
        ("自动换行", 17),
        ("垂直居中", 19),
        ("Demo", 13)
    ]
    
    var body: some View {
        VStack {
            Text("子视图垂直居中的自动换行布局")
                .font(.title)
                .padding()
            
            FlexboxLayout(horizontalSpacing: 12, verticalSpacing: 12) {
                ForEach(tags, id: \.0) { text, height in
                    Text(text)
                        .padding(.horizontal, 12)
                        .frame(height: CGFloat(height))  // 每个子视图高度不同，方便观察垂直居中
                        .background(Color.blue)
                        .foregroundColor(.white)
                        .cornerRadius(8)
                }
            }
            .padding()
        }
    }
}

struct FlexboxLayout_Previews: PreviewProvider {
    static var previews: some View {
        FlexboxLayoutDemo()
    }
}
